package mybitmap

// MyBitMap 自定义位图结构体
type MyBitMap struct {
	elem     []byte // 字节数组
	usedSize int    // 存储的元素个数
}

// InitBitMap 初始化函数
func InitBitMap() *MyBitMap {
	var bitMap MyBitMap
	bitMap.elem = make([]byte, 10)
	bitMap.usedSize = 0
	return &bitMap
}

// Set 添加元素
func (bitMap *MyBitMap) Set(num int) {
	if num < 0 {
		panic("num必须大于等于0!")
	}
	// 1. 获取字节数组对应存储下标
	var elemIndex = num / 8
	// 2. 获取所在字节的比特位
	var bitIndex = num % 8
	// 3. 使用或运算
	bitMap.elem[elemIndex] |= 1 << bitIndex
	// 4. 存储元素个数+1
	bitMap.usedSize++
}

// Get 查找某个元素是否存在
func (bitMap *MyBitMap) Get(num int) bool {
	if num < 0 {
		panic("num必须大于等于0!")
	}
	// 1. 获取字节数组对应存储下标
	var elemIndex = num / 8
	// 2. 获取所在字节的比特位
	var bitIndex = num % 8
	// 3. 使用与运算
	return !(bitMap.elem[elemIndex]&(1<<bitIndex) == 0)
}

// Reset 重置某个元素
func (bitMap *MyBitMap) Reset(num int) {
	if num < 0 {
		panic("num必须大于等于0!")
	}
	// 1. 获取字节数组对应存储下标
	var elemIndex = num / 8
	// 2. 获取所在字节的比特位
	var bitIndex = num % 8
	// 3. 查找元素是否存在
	if bitMap.Get(num) {
		bitMap.usedSize--
	}
	// 4. 使用 ~运算 + &运算
	bitMap.elem[elemIndex] &= ^(1 << bitIndex)
}

// Reset2 重置某个元素
func (bitMap *MyBitMap) Reset2(num int) {
	if num < 0 {
		panic("num必须大于等于0!")
	}
	// 1. 获取字节数组对应存储下标
	var elemIndex = num / 8
	// 2. 获取所在字节的比特位
	var bitIndex = num % 8
	// 3. 查找元素是否存在
	if bitMap.Get(num) {
		// 使用异或
		bitMap.elem[elemIndex] ^= 1 << bitIndex
		bitMap.usedSize--
	} else {
		// nothing to do....
	}
}

// GetUsedSize 获取已经存储元素个数
func (bitMap *MyBitMap) GetUsedSize() int {
	return bitMap.usedSize
}
